/* 
 * Copyright 2013 Sébastien Mouquet.
 * 
 * This file is part of ECovoiturage.
 * 
 * ECovoiturage is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * ECovoiturage is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with ECovoiturage. If not, see http://www.gnu.org/licenses/.
 */
package com.smouquet.ecovoiturage.ui.page;

import com.smouquet.ecovoiturage.core.bean.Config;
import com.smouquet.ecovoiturage.core.domain.Utilisateur;
import com.smouquet.ecovoiturage.ui.NotificationUtil;
import com.smouquet.ecovoiturage.ui.Wizard;
import com.vaadin.data.Validator;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.data.fieldgroup.PropertyId;
import com.vaadin.data.util.BeanItem;
import com.vaadin.server.Page;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * Etape d'installation de l'application : formulaire de création de
 * l'utilisateur "administrateur".
 * 
 * @author sebastien.mouquet
 */
public class InstallWizardUserAdminStep extends VerticalLayout implements Wizard.Step
{
    private Wizard wizard;
    private Config config;
    
    private FormLayout layout;
    
    @PropertyId("nom")
    private TextField tfNom;
    @PropertyId("email")
    private TextField tfEmail;
    @PropertyId("mdp")
    private PasswordField pfMdp;
    
    private FieldGroup fgForm;
    
    private Utilisateur utilisateur;
    
    
    public InstallWizardUserAdminStep()
    {
        layout();
    }
    
    
    private void layout()
    {
        layout = new FormLayout();
        layout.setImmediate(true);
        
        tfNom = new TextField("Nom");
        tfNom.setWidth(300, Unit.PIXELS);
        tfNom.setImmediate(true);
        tfNom.setRequired(true);
        tfNom.setMaxLength(80);
        tfNom.setValidationVisible(true);
        tfNom.setNullRepresentation("");
        
        tfEmail = new TextField("Email");
        tfEmail.setWidth(300, Unit.PIXELS);
        tfEmail.setImmediate(true);
        tfEmail.setRequired(true);
        tfEmail.setMaxLength(100);
        tfEmail.setValidationVisible(true);
        tfEmail.setNullRepresentation("");
     
        pfMdp = new PasswordField("Mot de passe");
        pfMdp.setWidth(300, Unit.PIXELS);
        pfMdp.setImmediate(true);
        pfMdp.setRequired(true);
        pfMdp.setMaxLength(15);
        pfMdp.setValidationVisible(true);
        pfMdp.setNullRepresentation("");
        
        layout.addComponent(tfNom);
        layout.addComponent(tfEmail);
        layout.addComponent(pfMdp);
        
        addComponent(layout);
        
        utilisateur = new Utilisateur();
        fgForm = new FieldGroup(new BeanItem<Utilisateur>(utilisateur));
        fgForm.bindMemberFields(this);
        
        setSizeFull();
        setMargin(true);
        setComponentAlignment(layout, Alignment.MIDDLE_CENTER);
    }

    
    @Override
    public void attachWizard(Wizard wizard)
    {
        this.wizard = wizard;
    }

    @Override
    public Component init()
    {
        wizard.setCaption("Installation - Création de l'utilisateur Administrateur");
        wizard.setFinishEnabled(true);
        wizard.setCancelEnabled(false);
        
        Wizard.Step previousStep = wizard.getSteps().get(wizard.getCurrentStepIndex()-1);
        config = ((InstallWizardDatabaseStep)previousStep).getConfig();
        
        return this;
    }

    @Override
    public void run() {}

    @Override
    public boolean onBeforePrevious() {
        return true;
    }

    @Override
    public void onAfterPrevious() {}

    @Override
    public boolean onBeforeNext() {
        return true;
    }

    @Override
    public void onAfterNext() {}

    @Override
    public boolean onBeforeFinish()
    {
        try
        {
            fgForm.commit();
            
            Class.forName(config.getJdbcDriver());
            Connection cx = DriverManager.getConnection(config.getJdbcUrl(), config.getJdbcUser(), config.getJdbcPassword());
            
            CallableStatement cs = cx.prepareCall("INSERT INTO utilisateur (nom, email, mdp, administrateur) VALUES (?, ?, ?, true)");
            cs.setString(1, utilisateur.getNom());
            cs.setString(2, utilisateur.getEmail());
            cs.setString(3, utilisateur.getMdp());
            
            int result = cs.executeUpdate();
            cx.commit();
            
            return result == 1;
            
        } catch(Validator.InvalidValueException ex) {
            NotificationUtil.showWarningNotification("Formulaire incomplet et/ou données invalides");
            return false;
        } catch(FieldGroup.CommitException ex) {
            NotificationUtil.showWarningNotification("Formulaire incomplet et/ou données invalides");
            return false;
        } catch(ClassNotFoundException ex) {
            NotificationUtil.showExceptionNotification(ex);
            return false;
        } catch(SQLException ex) {
            NotificationUtil.showExceptionNotification(ex);
            return false;
        }
    }

    @Override
    public void onAfterFinish()
    {
        String location = Page.getCurrent().getLocation().toString();
        location = location.substring(0, location.lastIndexOf("/"));
        location += "?restartApplication";
        Page.getCurrent().setLocation(location);
    }

    @Override
    public boolean onBeforeCancel() {
        return true;
    }

    @Override
    public void onAfterCancel() {}
}
